package com.duojuhe.coremodule.tracking.service.impl;

import com.duojuhe.cache.SystemDictCache;
import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.constant.DataScopeConstants;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.idgenerator.UUIDUtils;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.coremodule.BaseService;

import com.duojuhe.coremodule.system.entity.SystemDict;
import com.duojuhe.coremodule.tracking.entity.TrackingCategory;
import com.duojuhe.coremodule.tracking.entity.TrackingProcessItem;
import com.duojuhe.coremodule.tracking.mapper.TrackingCategoryMapper;
import com.duojuhe.coremodule.tracking.mapper.TrackingProcessItemMapper;
import com.duojuhe.coremodule.tracking.pojo.dto.category.*;
import com.duojuhe.coremodule.tracking.service.TrackingCategoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class TrackingCategoryServiceImpl extends BaseService implements TrackingCategoryService {
    @Resource
    private SystemDictCache systemDictCache;
    @Resource
    private TrackingCategoryMapper trackingCategoryMapper;
    @Resource
    private TrackingProcessItemMapper trackingProcessItemMapper;

    /**
     * 【查询所有溯源流程类别】溯源流程类别管理
     * @param req
     * @return
     */
    @DataScopeFilter
    @Override
    public ServiceResult<PageResult<List<QueryTrackingCategoryPageRes>>> queryTrackingCategoryPageResList(QueryTrackingCategoryPageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "sort desc,createTime desc, categoryId desc");
        List<QueryTrackingCategoryPageRes> list = trackingCategoryMapper.queryTrackingCategoryPageResList(req);
        for (QueryTrackingCategoryPageRes res:list){
            SystemDict dictStatus = systemDictCache.getSystemDictByDictCode(res.getStatusCode());
            res.setStatusName(dictStatus.getDictName());
            res.setStatusColor(dictStatus.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req, list);
    }



    /**
     * 【查询所有溯源流程类别】查询可供前端选择使用的溯源流程类别
     * @param req
     * @return
     */
    @DataScopeFilter(dataScope = DataScopeConstants.TENANT_ALL_DATA)
    @Override
    public ServiceResult<List<QuerySelectTrackingCategoryRes>> querySelectNormalTrackingCategoryResList(QuerySelectTrackingCategoryReq req) {
        PageHelperUtil.defaultOrderBy("sort desc,createTime desc, categoryId desc");
        List<QuerySelectTrackingCategoryRes> list = trackingCategoryMapper.querySelectNormalTrackingCategoryResList(req);
        return ServiceResult.ok(list);
    }


    /**
     * 【保存】溯源流程类别产品
     * @param req
     * @return
     */
    @Override
    public ServiceResult saveTrackingCategory(SaveTrackingCategoryReq req) {
        //分类ID
        String categoryId = UUIDUtils.getUUID32();
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前时间
        Date date = new Date();
        TrackingCategory category = new TrackingCategory();
        category.setCategoryId(categoryId);
        category.setCategoryName(req.getCategoryName());
        category.setCreateTime(date);
        category.setUpdateTime(date);
        category.setSort(req.getSort());
        category.setCreateUserId(userTokenInfoVo.getUserId());
        category.setUpdateUserId(userTokenInfoVo.getUserId());
        category.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        category.setTenantId(userTokenInfoVo.getTenantId());
        category.setStatusCode(req.getStatusCode());
        trackingCategoryMapper.insertSelective(category);
        return ServiceResult.ok(categoryId);
    }

    /**
     * 【修改】溯源流程类别产品
     * @param req
     * @return
     */
    @Override
    public ServiceResult updateTrackingCategory(UpdateTrackingCategoryReq req) {
        //分类ID
        String categoryId = req.getCategoryId();
        TrackingCategory categoryOld = trackingCategoryMapper.selectByPrimaryKey(categoryId);
        if (categoryOld==null){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前时间
        Date date = new Date();
        TrackingCategory category = new TrackingCategory();
        category.setCategoryId(categoryId);
        category.setCategoryName(req.getCategoryName());
        category.setUpdateTime(date);
        category.setSort(req.getSort());
        category.setUpdateUserId(userTokenInfoVo.getUserId());
        category.setStatusCode(req.getStatusCode());
        trackingCategoryMapper.updateByPrimaryKeySelective(category);
        return ServiceResult.ok(categoryId);
    }

    /**
     * 【删除】根据溯源流程类别ID删除溯源流程类别，注意一次仅能删除一个溯源流程类别，存在绑定关系的则不能删除
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult deleteTrackingCategoryByCategoryId(TrackingCategoryIdReq req) {
        String categoryId = req.getCategoryId();
        TrackingCategory categoryOld = trackingCategoryMapper.selectByPrimaryKey(categoryId);
        if (categoryOld == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //判断分类是否被流程项关联使用
        checkRelationTrackingItem(categoryId);
        //分类删除
        trackingCategoryMapper.deleteByPrimaryKey(categoryId);
        return ServiceResult.ok(categoryId);
    }


    /**
     * 【私有方法，辅助其他接口方法使用】 根据分类id查询是否存在流程项关联
     */
    private void checkRelationTrackingItem(String categoryId) {
        if (StringUtils.isBlank(categoryId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_CATEGORY_RELATION_ITEM_NOT_DELETE);
        }
        Example example = new Example(TrackingProcessItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("trackingCategoryId", categoryId);
        if(trackingProcessItemMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.TRACKING_CATEGORY_RELATION_ITEM_NOT_DELETE);
        }
    }
}
